#ifndef LC_PROC2_H_
#define LC_PROC2_H_

#include <assert.h>
#include <map>
#include <lagniappe/ProcElement.h>
#include "simpleMutex.h"
#include "BasicTimer.h"
#include <iostream>

#include "lc_CC2_CommChannel.h"
#include "lc_CC0_CommChannel.h"
#include "lc_CC1_CommChannel.h"
#include "lc_CC3_CommChannel.h"
#include "lc_CC4_CommChannel.h"
#include "lc_CC5_CommChannel.h"
#include "lc_CC6_CommChannel.h"
#include "lc_CC7_CommChannel.h"
#include "lc_CC8_CommChannel.h"
#include "lc_CC9_CommChannel.h"
#include "lc_CC10_CommChannel.h"
#include "lc_CC11_CommChannel.h"
#include "lc_CC12_CommChannel.h"
#include "lc_CC13_CommChannel.h"
#include "lc_CC14_CommChannel.h"
#include "lc_CC15_CommChannel.h"
#include "lc_Mem0_Memory.h"
#include "Thread.hh"


class Proc2 : public lagniappe::ProcElement, simpleMtx {
private:
	lagniappe::CommChannel * sourceChannel;
	std::map<lagniappe::ProcElement *, lagniappe::CommChannel *> chanMap;
	Thread coreThread;
	timer::BasicTimer timer;
	virtual lagniappe::RCon * getRCon() {assert(sourceChannel != NULL); return sourceChannel->get();}

public:
	Proc2(bool f = false) : lagniappe::ProcElement(f) {}
	virtual ~Proc2() {this->destroy();}
	void setSrcChan(lagniappe::CommChannel * sc) {sourceChannel = sc;}
	void addDestChan(lagniappe::ProcElement * p, lagniappe::CommChannel * dc) {chanMap[p] =  dc;}

	virtual void processRequest(lagniappe::RCon * rc) {assert(sourceChannel != NULL); assert(rc != NULL); sourceChannel->put(rc);}
	virtual void init() {coreThread.init(lagniappe::startProc, (void *)this);}
	virtual void destroy() {coreThread.kill();}
	virtual bool isOverloaded(lagniappe::RCon * rc) {if(freeze) {return false;} else if(sourceChannel->getCount() > rc->getOp()->getQueueThreshold()) {return true;} else {return false;}}
	virtual void unFreeze() {lock(); freeze = false; unlock();}
	virtual void getThread() {std::cout << coreThread.getThread();}
	virtual void startTimer() {timer.start();}
	virtual double endTimer() {return timer.stop();}
	virtual void profileWait() {wait();}
	virtual void profileNotify() {notify();}
	virtual void profileLock() {lock();}
	virtual void profileUnlock() {unlock();}

};
#endif

